package com.jason.data.controller;

import com.jason.data.entity.User;
import com.jason.data.interfaces.UserMongoRepo;
import com.mongodb.client.result.UpdateResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.AddFieldsOperation;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;

@RestController
@Slf4j
public class TestController {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private UserMongoRepo userMongoRepo;

    @GetMapping("/query")
    public Object test0(){
        List<User> all = userMongoRepo.findAll();
        return all;
    }
    @GetMapping("/find/{name}/{age}")
    public Object test1(@PathVariable("name") String name,@PathVariable("age") int age){
//        ExecutableFindOperation.ExecutableFind<User> query = mongoTemplate.query(User.class);
//        Object[] array = query.stream().toArray();

        //where name=张三 and age=20
        Query andQuery = new Query();
        andQuery.addCriteria(Criteria.where("name").is(name).and("age").gt(age));
        andQuery.with(Sort.by(Sort.Order.desc("age")));
        List<User> users = mongoTemplate.find(andQuery, User.class);
        System.out.println("and查询："+users);

        //where name=张三 and (age>20 or 1=1 )
        Query orQuery = new Query();
        orQuery.addCriteria(Criteria.where("name").is(name).orOperator(Criteria.where("age").gt(age)));
        orQuery.with(Sort.by(Sort.Order.desc("age")));
        List<User> orUsers = mongoTemplate.find(orQuery, User.class);
        System.out.println("or查询："+orUsers);

        Query Query = new Query();
        Query.fields().exclude("_id");
        Query.fields().exclude("birth");
        Query.fields().exclude("phone");
        //where name=张三 or age>20
        Query.addCriteria(new Criteria().orOperator(Criteria.where("name").is(name),Criteria.where("age").gt(age)));
        Query.with(Sort.by(Sort.Order.desc("age")));
        List<Map> users1 = mongoTemplate.find(Query, Map.class,"users");
        System.out.println("or查询："+users1);


        return users1;
    }

    @GetMapping("/insert")
    public Object inserts(){
        List<User> list  = new ArrayList<>();
        Random r = new Random(100);
        for (int i = 0; i < 3; i++) {
            int i1 = r.nextInt(100);
            User user = new User();
            user.setName("名称("+i1+")_"+i);
            user.setAge(20);
            user.setAddr("北京—"+i1+"-"+i);
            user.setPhone("13112345678");
            user.setBirth(new Date(2000,10,10));
            list.add(user);
        }

        Collection<User> users = mongoTemplate.insertAll(list);
//        Collection<User> users = mongoTemplate.insert(list, User.class);

        return users.toString();
    }

    @GetMapping("/aggregate")
    public Object aggregate(){
        AddFieldsOperation build = Aggregation.addFields().addFieldWithValue("name", "$_id").build();
        AggregationOperation project = Aggregation.project("name","total").andExclude("_id");
        AggregationOperation groupOperation = Aggregation.group("name").sum("age").as("total");
        Aggregation aggregation = Aggregation.newAggregation(groupOperation,build,project);

        AggregationResults<Map> aggregate = mongoTemplate.aggregate(aggregation,"users", Map.class);
        return aggregate.getMappedResults();
    }
    @GetMapping("/update/{age}/{sex}")
    public Object update(@PathVariable("sex") String sex,@PathVariable("age") int age){

        Query query = new Query();
        query.addCriteria(Criteria.where("age").gt(age));
        Update update = new Update();
        update.set("sex",sex);
        UpdateResult users = mongoTemplate.updateMulti(query, update, "users");

        return users.getModifiedCount();
    }

}
